/*************************************************************************

            (c) Copyright 2019 by 天翼物联科技有限公司. All rights reserved.

*************************************************************************/
#include "ctiot_mqtt_sdk_tmodel.h"
#include "string.h"
#include "ctiot_mqtt_sdk.h"
#include "ctiot_log.h"
#include "cJSON.h"
#include "abstract_os.h"
#include "ctiot_abstract_mqtt.h"
#if DATA_MODE >0
#define MAX_SRV_NUM 9
mqtt_client_s *get_client_handle(void);
typedef struct mqtt_srv
{
	char *srvIdr; 
	void(*srv_cb)(MAL_message_data *md);
} mqtt_srv_s;
#if (DATA_MODE == 1 || DATA_MODE == 2)
static void CtiotMqttSeparateDnSetReportPeriodCb(MAL_message_data *md);
static void CtiotMqttSeparateDnAirConditionerOnoffCmdCb(MAL_message_data *md);
static void CtiotMqttSeparateDnSetAutoControlCb(MAL_message_data *md);
mqtt_srv_s devSrv[MAX_SRV_NUM] =
{
	{.srvIdr = "set_report_period", .srv_cb = CtiotMqttSeparateDnSetReportPeriodCb, },
	{.srvIdr = "air_conditioner_onoff_cmd", .srv_cb = CtiotMqttSeparateDnAirConditionerOnoffCmdCb, },
	{.srvIdr = "set_auto_control", .srv_cb = CtiotMqttSeparateDnSetAutoControlCb, },
};
#elif DATA_MODE == 3
static void CtiotMqttIntegrateDecodeSetReportPeriodCb(MAL_message_data *md);
static void CtiotMqttIntegrateDecodeAirConditionerOnoffCmdCb(MAL_message_data *md);
static void CtiotMqttIntegrateDecodeSetAutoControlCb(MAL_message_data *md);
mqtt_srv_s devSrv[MAX_SRV_NUM] =
{
	{.srvIdr = "set_report_period", .srv_cb = CtiotMqttIntegrateDecodeSetReportPeriodCb, },
	{.srvIdr = "air_conditioner_onoff_cmd", .srv_cb = CtiotMqttIntegrateDecodeAirConditionerOnoffCmdCb, },
	{.srvIdr = "set_auto_control", .srv_cb = CtiotMqttIntegrateDecodeSetAutoControlCb, },
};
#endif
void CtiotDnMqttData(void *md)
{
	int i = 0; 
	MAL_message_data *pmd = md;
	if (pmd == NULL)
		return; 
	//we have to find the right message handler - indexed by topic
	for (i = 0; i < MAX_SRV_NUM; ++i)
	{
		if ((devSrv[i].srvIdr != NULL) &&
			strlen(devSrv[i].srvIdr) == pmd->topicName->lenstring.len &&
			strncmp(devSrv[i].srvIdr, pmd->topicName->lenstring.data, pmd->topicName->lenstring.len) == 0)
		{
			if (devSrv[i].srv_cb != NULL)
			{
				devSrv[i].srv_cb(md);
				break; 
			}
		}
	}
}
#if (DATA_MODE == 1 || DATA_MODE == 2)
static void CtiotMqttSeparateDnSetReportPeriodCb(MAL_message_data *md)
{
	if (md->message->payload == NULL)
	{
		CTIOT_LOG(LOG_FATAL, "null point");
		return;
	}
	char *payload = md->message->payload;
	CTIOT_LOG(LOG_INFO, "payload=%s ",payload);
	mqtt_client_s *m_mqtt_client = get_client_handle();
	CtiotSrvCbS *ctiot_callback = m_mqtt_client->downDataCallback;
	if (ctiot_callback != NULL && ctiot_callback->set_report_period_callback != NULL)
	{
	ctiot_callback->set_report_period_callback(payload);
	}
}
static void CtiotMqttSeparateDnAirConditionerOnoffCmdCb(MAL_message_data *md)
{
	if (md->message->payload == NULL)
	{
		CTIOT_LOG(LOG_FATAL, "null point");
		return;
	}
	char *payload = md->message->payload;
	CTIOT_LOG(LOG_INFO, "payload=%s ",payload);
	mqtt_client_s *m_mqtt_client = get_client_handle();
	CtiotSrvCbS *ctiot_callback = m_mqtt_client->downDataCallback;
	if (ctiot_callback != NULL && ctiot_callback->air_conditioner_onoff_cmd_callback != NULL)
	{
	ctiot_callback->air_conditioner_onoff_cmd_callback(payload);
	}
}
static void CtiotMqttSeparateDnSetAutoControlCb(MAL_message_data *md)
{
	if (md->message->payload == NULL)
	{
		CTIOT_LOG(LOG_FATAL, "null point");
		return;
	}
	char *payload = md->message->payload;
	CTIOT_LOG(LOG_INFO, "payload=%s ",payload);
	mqtt_client_s *m_mqtt_client = get_client_handle();
	CtiotSrvCbS *ctiot_callback = m_mqtt_client->downDataCallback;
	if (ctiot_callback != NULL && ctiot_callback->set_auto_control_callback != NULL)
	{
	ctiot_callback->set_auto_control_callback(payload);
	}
}
#endif
#if (DATA_MODE == 2 || DATA_MODE == 3)
#ifndef HEAP_TRACE
cJSON_Hooks g_cJSON_Hooks = { ctiot_malloc, ctiot_free };
#else
cJSON_Hooks g_cJSON_Hooks = { malloc_trace, free_trace };
#endif
void CtiotTmodelInit(void)
{
	cJSON_InitHooks(&g_cJSON_Hooks);
}
void CtiotTmodelFree(void *p)
{
	ctiot_free(p);
}
static CTIOT_RESULT_CODE CtiotMqttValidate(CtiotMqttPara para)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	uint32_t i = 0;
	for(;i < para.count;i++){
		switch(para.paraList[i].ctiotParaType){
			case CTIOT_INT:
			{
				if(para.paraList[i].u.ctiotInt.val < para.paraList[i].u.ctiotInt.min || para.paraList[i].u.ctiotInt.val > para.paraList[i].u.ctiotInt.max){
					CTIOT_LOG(LOG_FATAL, "MSG PARA ERROR");
					return CTIOT_ENCODE_ERROR;
				}
				break;
			}
			case CTIOT_DOUBLE:
			{
				if(para.paraList[i].u.ctiotDouble.val < para.paraList[i].u.ctiotDouble.min || para.paraList[i].u.ctiotDouble.val > para.paraList[i].u.ctiotDouble.max){
					CTIOT_LOG(LOG_FATAL, "MSG PARA ERROR");
					return CTIOT_ENCODE_ERROR;
				}
				break;
			}
			case CTIOT_FLOAT:
			{
				if(para.paraList[i].u.ctiotFloat.val < para.paraList[i].u.ctiotFloat.min || para.paraList[i].u.ctiotFloat.val > para.paraList[i].u.ctiotFloat.max){
					CTIOT_LOG(LOG_FATAL, "MSG PARA ERROR");
					return CTIOT_ENCODE_ERROR;
				}
				break;
			}
			case CTIOT_STR:
			{
				if(para.paraList[i].u.ctiotStr.val != NULL && (strlen(para.paraList[i].u.ctiotStr.val) < para.paraList[i].u.ctiotStr.minLen || strlen(para.paraList[i].u.ctiotStr.val) > para.paraList[i].u.ctiotStr.maxLen)){
					CTIOT_LOG(LOG_FATAL, "MSG PARA ERROR");
					return CTIOT_ENCODE_ERROR;
				}
				break;
			}
			case CTIOT_ENUM:
			{
				break;
			}
			case CTIOT_BOOL:
			{
				break;
			}
			case CTIOT_DATE:
			{
				break;
			}
			default:
			{
				CTIOT_LOG(LOG_FATAL, "MSG TYPE ERROR");
				return CTIOT_ENCODE_ERROR;
			}
		}
	}
	return ret;
}
CTIOT_RESULT_CODE CtiotMqttMsgEncode(CtiotMqttPara para,char** payload)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	cJSON *root = cJSON_CreateObject();
	if(root == NULL)
	{
		goto failed;
	}
	cJSON *node = NULL;
	int i = 0;
	for(;i < para.count;i++){
		switch(para.paraList[i].ctiotParaType){
			case CTIOT_INT:
			{
				node = cJSON_CreateNumber(para.paraList[i].u.ctiotInt.val);
				if(node == NULL)
				{
					goto failed;
				}
				cJSON_AddItemToObjectCS(root,para.paraList[i].paraName,node);
				break;
			}
			case CTIOT_DOUBLE:
			{
				node = cJSON_CreateNumber(para.paraList[i].u.ctiotDouble.val);
				if(node == NULL)
				{
					goto failed;
				}
				cJSON_AddItemToObjectCS(root,para.paraList[i].paraName,node);
				break;
			}
			case CTIOT_FLOAT:
			{
				node = cJSON_CreateNumber(para.paraList[i].u.ctiotFloat.val);
				if(node == NULL)
				{
					goto failed;
				}
				cJSON_AddItemToObjectCS(root,para.paraList[i].paraName,node);
				break;
			}
			case CTIOT_STR:
			{
				if(para.paraList[i].u.ctiotStr.val == NULL)
				{
					node = cJSON_CreateNull();
					if (node == NULL)
					{
						goto failed;
					}
				}
				else
				{
					node = cJSON_CreateString(para.paraList[i].u.ctiotStr.val);
					if(node == NULL)
					{
					goto failed;
					}
				}
				cJSON_AddItemToObjectCS(root,para.paraList[i].paraName,node);
				break;
			}
			case CTIOT_ENUM:
			{
				node = cJSON_CreateNumber(para.paraList[i].u.ctiotEnum.val);
				if(node == NULL)
				{
					goto failed;
				}
				cJSON_AddItemToObjectCS(root,para.paraList[i].paraName,node);
				break;
			}
			case CTIOT_BOOL:
			{
				node = cJSON_CreateBool(para.paraList[i].u.ctiotBool.val);
				if(node == NULL)
				{
					goto failed;
				}
				cJSON_AddItemToObjectCS(root,para.paraList[i].paraName,node);
				break;
			}
			case CTIOT_DATE:
			{
				node = cJSON_CreateNumber(para.paraList[i].u.ctiotDate.val);
				if(node == NULL)
				{
					goto failed;
				}
				cJSON_AddItemToObjectCS(root,para.paraList[i].paraName,node);
				break;
			}
			default:
			{
				if(root){
					cJSON_Delete(root);
				}
				return CTIOT_ENCODE_ERROR;
			}
		}
	}
	(*payload) = cJSON_Print(root);
	if((*payload) == NULL)
	{
		goto failed;
	}
	cJSON_Delete(root);
	CTIOT_LOG(LOG_INFO, "report:%s!",(*payload));
	return ret;
failed:
	cJSON_Delete(root);
	return CTIOT_MALLOC_ERROR;
}
CTIOT_RESULT_CODE CtiotMqttMsgResponseEncode(CtiotMqttPara para,uint32_t taskId,char** payload)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	cJSON *node = NULL;
	cJSON *root = cJSON_CreateObject();
	if(root == NULL)
	{
		goto failed;
	}
	cJSON_AddItemToObjectCS(root,"taskId",cJSON_CreateNumber(taskId));
	cJSON *paylaodItem = cJSON_CreateObject();
	if(root == NULL)
	{
		goto failed;
	}
	uint32_t i = 0;
	for(;i < para.count;i++){
		switch(para.paraList[i].ctiotParaType){
			case CTIOT_INT:
			{
				node = cJSON_CreateNumber(para.paraList[i].u.ctiotInt.val);
				if(node == NULL)
				{
					goto failed;
				}
				cJSON_AddItemToObjectCS(paylaodItem,para.paraList[i].paraName,node);
				break;
			}
			case CTIOT_DOUBLE:
			{
				node = cJSON_CreateNumber(para.paraList[i].u.ctiotDouble.val);
				if(node == NULL)
				{
					goto failed;
				}
				cJSON_AddItemToObjectCS(paylaodItem,para.paraList[i].paraName,node);
				break;
			}
			case CTIOT_FLOAT:
			{
				node = cJSON_CreateNumber(para.paraList[i].u.ctiotFloat.val);
				if(node == NULL)
				{
					goto failed;
				}
				cJSON_AddItemToObjectCS(paylaodItem,para.paraList[i].paraName,node);
				break;
			}
			case CTIOT_STR:
			{
				node = cJSON_CreateString(para.paraList[i].u.ctiotStr.val);
				if(node == NULL)
				{
					goto failed;
				}
				cJSON_AddItemToObjectCS(paylaodItem,para.paraList[i].paraName,node);
				break;
			}
			case CTIOT_ENUM:
			{
				node = cJSON_CreateNumber(para.paraList[i].u.ctiotEnum.val);
				if(node == NULL)
				{
					goto failed;
				}
				cJSON_AddItemToObjectCS(paylaodItem,para.paraList[i].paraName,node);
				break;
			}
			case CTIOT_BOOL:
			{
				node = cJSON_CreateBool(para.paraList[i].u.ctiotBool.val);
				if(node == NULL)
				{
					goto failed;
				}
				cJSON_AddItemToObjectCS(paylaodItem,para.paraList[i].paraName,node);
				break;
			}
			case CTIOT_DATE:
			{
				node = cJSON_CreateNumber(para.paraList[i].u.ctiotDate.val);
				if(node == NULL)
				{
					goto failed;
				}
				cJSON_AddItemToObjectCS(paylaodItem,para.paraList[i].paraName,node);
				break;
			}
			default:
			{
				if(root){
					cJSON_Delete(root);
				}
				if(paylaodItem){
					cJSON_Delete(paylaodItem);
				}
				return CTIOT_ENCODE_ERROR;
			}
		}
	}
	cJSON_AddItemToObjectCS(root,"resultPayload",paylaodItem);
	(*payload) = cJSON_Print(root);
	if((*payload) == NULL)
	{
		goto failed;
	}
	cJSON_Delete(root);
	CTIOT_LOG(LOG_INFO, "response:%s!",(*payload));
	return ret;
failed:
	cJSON_Delete(root);
	return CTIOT_MALLOC_ERROR;
}
static CtiotMqttPara *CtiotMqttJsonParsing(char *json)
{
	CtiotMqttPara *para = NULL;
	para = ctiot_malloc(sizeof(CtiotMqttPara));
	if(para == NULL)
	{
		return NULL;
	}
	uint32_t count = 0;
	cJSON *root = cJSON_Parse(json);
	if(root == NULL)
	{
		return NULL;
	}
	cJSON *payloadItem = cJSON_GetObjectItem(root,"payload");
	cJSON *taskIdItem = cJSON_GetObjectItem(root,"taskId");
	para->paraList[count].ctiotParaType = CTIOT_INT;
	para->paraList[count].u.ctiotInt.val = taskIdItem->valueint;
	para->paraList[count].paraName = ctiot_strdup("taskId");
	count ++;
	cJSON *c = payloadItem->child;
	while(c != NULL)
	{
		switch(c->type){
			case cJSON_False:
			case cJSON_True:
				para->paraList[count].ctiotParaType = CTIOT_BOOL;
				para->paraList[count].u.ctiotBool.val = c->valueint;
				para->paraList[count].paraName = (char *)ctiot_malloc(strlen(c->string)+1);
				if(para->paraList[count].paraName == NULL)
				{
					goto failed;
				}
				strcpy(para->paraList[count].paraName,c->string);
				break;
			case cJSON_Number:
				para->paraList[count].ctiotParaType = CTIOT_DOUBLE;
				para->paraList[count].u.ctiotDouble.val = c->valuedouble;
				para->paraList[count].paraName = (char *)ctiot_malloc(strlen(c->string)+1);
				if(para->paraList[count].paraName == NULL)
				{
					goto failed;
				}
				strcpy(para->paraList[count].paraName,c->string);
				break;
			case cJSON_String:
				para->paraList[count].ctiotParaType = CTIOT_STR;
				para->paraList[count].u.ctiotStr.val = (char *)ctiot_malloc(strlen(c->valuestring)+1);
				if(para->paraList[count].u.ctiotStr.val == NULL)
				{
					goto failed;
				}
				strcpy(para->paraList[count].u.ctiotStr.val,c->valuestring);
				para->paraList[count].paraName = (char *)ctiot_malloc(strlen(c->string)+1);
				if(para->paraList[count].paraName == NULL)
				{
					CtiotTmodelFree(para->paraList[count].u.ctiotStr.val);
					goto failed;
				}
				strcpy(para->paraList[count].paraName,c->string);
				break;
			case cJSON_NULL:
				break;
		}
		count ++;
		c = c->next;
	}
	para->count = count;
	cJSON_Delete(root);
	return para;
failed:
	cJSON_Delete(root);
	uint32_t i = 0;
	while (i < count)
	{
		CtiotTmodelFree(para->paraList[i].paraName);
		if(para->paraList[i].ctiotParaType == CTIOT_STR)
		{
			CtiotTmodelFree(para->paraList[i].u.ctiotStr.val);
		}
		i++;
	}
	CtiotTmodelFree(para);
	return NULL;
}
CTIOT_RESULT_CODE CtiotMqttEncodeDataReport(DataReportS* para,char** payload)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	CtiotMqttPara  tmpPara = { 0 };
	tmpPara.count = 2;
	tmpPara.paraList[0].paraName = "temperature_data";
	tmpPara.paraList[0].ctiotParaType = CTIOT_FLOAT;
	tmpPara.paraList[0].u.ctiotFloat.val = para->temperature_data;
	tmpPara.paraList[0].u.ctiotFloat.min = -40.0;
	tmpPara.paraList[0].u.ctiotFloat.max = 100.0;
	tmpPara.paraList[1].paraName = "humidity_data";
	tmpPara.paraList[1].ctiotParaType = CTIOT_INT;
	tmpPara.paraList[1].u.ctiotInt.val = para->humidity_data;
	tmpPara.paraList[1].u.ctiotInt.min = 0;
	tmpPara.paraList[1].u.ctiotInt.max = 100;
	ret = CtiotMqttValidate(tmpPara);
	if (ret != CTIOT_SUCCESS)
	{
		return ret;
	}
	ret = CtiotMqttMsgEncode(tmpPara, payload);
	return ret;
}
CTIOT_RESULT_CODE CtiotMqttDecodeSetReportPeriodPara(char * payload,SetReportPeriodS * outPara)
{
	uint32_t i = 0;
	SetReportPeriodS  para = { 0 };
	CtiotMqttPara* paraHead = CtiotMqttJsonParsing(payload);
	if (paraHead == NULL)
	{
		CTIOT_LOG(LOG_FATAL, "ctiot_mqtt_decode error!");
		return CTIOT_DECODE_ERROR;
	}
	if (outPara == NULL)
	{
		CTIOT_LOG(LOG_FATAL, "ctiot_mqtt_decode Para error!");
		return CTIOT_PARA_ERROR;
	}
	while (i < paraHead->count)
	{
		char* paraName = paraHead->paraList[i].paraName;
		if (strcmp(paraName, "taskId") == 0)
		{
			para.taskId = (uint32_t)paraHead->paraList[i].u.ctiotInt.val;
		}
		else if(strcmp(paraName,"report_period")==0)
		{
			para.report_period= (int32_t)paraHead->paraList[i].u.ctiotDouble.val;
		}
		i++;
	}
	memcpy(outPara, &para, sizeof(para));
	i = 0;
	while (i < paraHead->count)
	{
		CtiotTmodelFree(paraHead->paraList[i].paraName);
		if (paraHead->paraList[i].ctiotParaType == CTIOT_STR)
		{
			CtiotTmodelFree(paraHead->paraList[i].u.ctiotStr.val);
		}
		i++;
	}
	CtiotTmodelFree(paraHead);
	return CTIOT_SUCCESS;
}
CTIOT_RESULT_CODE CtiotMqttEncodeAirConditionerOnoffResp(AirConditionerOnoffRespS* para,char** payload)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	CtiotMqttPara  tmpPara = { 0 };
	tmpPara.count = 2;
	tmpPara.paraList[0].paraName = "air_conditioner_onoff";
	tmpPara.paraList[0].ctiotParaType = CTIOT_ENUM;
	tmpPara.paraList[0].u.ctiotEnum.val = para->air_conditioner_onoff;
	tmpPara.paraList[1].paraName = "act_result";
	tmpPara.paraList[1].ctiotParaType = CTIOT_ENUM;
	tmpPara.paraList[1].u.ctiotEnum.val = para->act_result;
	ret = CtiotMqttValidate(tmpPara);
	if (ret != CTIOT_SUCCESS)
	{
		return ret;
	}
	ret = CtiotMqttMsgResponseEncode(tmpPara, para->taskId, payload);
	return ret;
}
CTIOT_RESULT_CODE CtiotMqttDecodeAirConditionerOnoffCmdPara(char * payload,AirConditionerOnoffCmdS * outPara)
{
	uint32_t i = 0;
	AirConditionerOnoffCmdS  para = { 0 };
	CtiotMqttPara* paraHead = CtiotMqttJsonParsing(payload);
	if (paraHead == NULL)
	{
		CTIOT_LOG(LOG_FATAL, "ctiot_mqtt_decode error!");
		return CTIOT_DECODE_ERROR;
	}
	if (outPara == NULL)
	{
		CTIOT_LOG(LOG_FATAL, "ctiot_mqtt_decode Para error!");
		return CTIOT_PARA_ERROR;
	}
	while (i < paraHead->count)
	{
		char* paraName = paraHead->paraList[i].paraName;
		if (strcmp(paraName, "taskId") == 0)
		{
			para.taskId = (uint32_t)paraHead->paraList[i].u.ctiotInt.val;
		}
		else if(strcmp(paraName,"air_conditioner_onoff")==0)
		{
			para.air_conditioner_onoff= (int32_t)paraHead->paraList[i].u.ctiotDouble.val;
		}
		i++;
	}
	memcpy(outPara, &para, sizeof(para));
	i = 0;
	while (i < paraHead->count)
	{
		CtiotTmodelFree(paraHead->paraList[i].paraName);
		if (paraHead->paraList[i].ctiotParaType == CTIOT_STR)
		{
			CtiotTmodelFree(paraHead->paraList[i].u.ctiotStr.val);
		}
		i++;
	}
	CtiotTmodelFree(paraHead);
	return CTIOT_SUCCESS;
}
CTIOT_RESULT_CODE CtiotMqttEncodeIrSensorReport(IrSensorReportS* para,char** payload)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	CtiotMqttPara  tmpPara = { 0 };
	tmpPara.count = 1;
	tmpPara.paraList[0].paraName = "ir_sensor_data";
	tmpPara.paraList[0].ctiotParaType = CTIOT_ENUM;
	tmpPara.paraList[0].u.ctiotEnum.val = para->ir_sensor_data;
	ret = CtiotMqttValidate(tmpPara);
	if (ret != CTIOT_SUCCESS)
	{
		return ret;
	}
	ret = CtiotMqttMsgEncode(tmpPara, payload);
	return ret;
}
CTIOT_RESULT_CODE CtiotMqttEncodeInfoReport(InfoReportS* para,char** payload)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	CtiotMqttPara  tmpPara = { 0 };
	tmpPara.count = 2;
	tmpPara.paraList[0].paraName = "hardware_version";
	tmpPara.paraList[0].ctiotParaType = CTIOT_STR;
	tmpPara.paraList[0].u.ctiotStr.val = para->hardware_version;
	tmpPara.paraList[0].u.ctiotStr.minLen = 0;
	tmpPara.paraList[0].u.ctiotStr.maxLen = 100;
	tmpPara.paraList[1].paraName = "software_version";
	tmpPara.paraList[1].ctiotParaType = CTIOT_STR;
	tmpPara.paraList[1].u.ctiotStr.val = para->software_version;
	tmpPara.paraList[1].u.ctiotStr.minLen = 0;
	tmpPara.paraList[1].u.ctiotStr.maxLen = 100;
	ret = CtiotMqttValidate(tmpPara);
	if (ret != CTIOT_SUCCESS)
	{
		return ret;
	}
	ret = CtiotMqttMsgEncode(tmpPara, payload);
	return ret;
}
CTIOT_RESULT_CODE CtiotMqttEncodeSetAutoControlResp(SetAutoControlRespS* para,char** payload)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	CtiotMqttPara  tmpPara = { 0 };
	tmpPara.count = 2;
	tmpPara.paraList[0].paraName = "auto_control";
	tmpPara.paraList[0].ctiotParaType = CTIOT_ENUM;
	tmpPara.paraList[0].u.ctiotEnum.val = para->auto_control;
	tmpPara.paraList[1].paraName = "act_result";
	tmpPara.paraList[1].ctiotParaType = CTIOT_ENUM;
	tmpPara.paraList[1].u.ctiotEnum.val = para->act_result;
	ret = CtiotMqttValidate(tmpPara);
	if (ret != CTIOT_SUCCESS)
	{
		return ret;
	}
	ret = CtiotMqttMsgResponseEncode(tmpPara, para->taskId, payload);
	return ret;
}
CTIOT_RESULT_CODE CtiotMqttDecodeSetAutoControlPara(char * payload,SetAutoControlS * outPara)
{
	uint32_t i = 0;
	SetAutoControlS  para = { 0 };
	CtiotMqttPara* paraHead = CtiotMqttJsonParsing(payload);
	if (paraHead == NULL)
	{
		CTIOT_LOG(LOG_FATAL, "ctiot_mqtt_decode error!");
		return CTIOT_DECODE_ERROR;
	}
	if (outPara == NULL)
	{
		CTIOT_LOG(LOG_FATAL, "ctiot_mqtt_decode Para error!");
		return CTIOT_PARA_ERROR;
	}
	while (i < paraHead->count)
	{
		char* paraName = paraHead->paraList[i].paraName;
		if (strcmp(paraName, "taskId") == 0)
		{
			para.taskId = (uint32_t)paraHead->paraList[i].u.ctiotInt.val;
		}
		else if(strcmp(paraName,"auto_control")==0)
		{
			para.auto_control= (int32_t)paraHead->paraList[i].u.ctiotDouble.val;
		}
		i++;
	}
	memcpy(outPara, &para, sizeof(para));
	i = 0;
	while (i < paraHead->count)
	{
		CtiotTmodelFree(paraHead->paraList[i].paraName);
		if (paraHead->paraList[i].ctiotParaType == CTIOT_STR)
		{
			CtiotTmodelFree(paraHead->paraList[i].u.ctiotStr.val);
		}
		i++;
	}
	CtiotTmodelFree(paraHead);
	return CTIOT_SUCCESS;
}
CTIOT_RESULT_CODE CtiotMqttEncodeSetReportPeriodResp(SetReportPeriodRespS* para,char** payload)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	CtiotMqttPara  tmpPara = { 0 };
	tmpPara.count = 2;
	tmpPara.paraList[0].paraName = "report_period";
	tmpPara.paraList[0].ctiotParaType = CTIOT_INT;
	tmpPara.paraList[0].u.ctiotInt.val = para->report_period;
	tmpPara.paraList[0].u.ctiotInt.min = 1;
	tmpPara.paraList[0].u.ctiotInt.max = 86400;
	tmpPara.paraList[1].paraName = "act_result";
	tmpPara.paraList[1].ctiotParaType = CTIOT_ENUM;
	tmpPara.paraList[1].u.ctiotEnum.val = para->act_result;
	ret = CtiotMqttValidate(tmpPara);
	if (ret != CTIOT_SUCCESS)
	{
		return ret;
	}
	ret = CtiotMqttMsgResponseEncode(tmpPara, para->taskId, payload);
	return ret;
}
#if (DATA_MODE ==3)
CTIOT_RESULT_CODE CtiotMqttSendDataReportData(DataReportS *para, mqtt_qos_e qos, ctiot_mqtt_msg_s *ptrMsg)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	char *payload = NULL;
	ret = CtiotMqttEncodeDataReport(para, &payload);
	if (ret != CTIOT_SUCCESS)
	{
		return ret;
	}
	ret = ctiot_mqtt_send_data("data_report", qos, payload, ptrMsg);
	CtiotTmodelFree(payload);
	return ret;
}
static void CtiotMqttIntegrateDecodeSetReportPeriodCb(MAL_message_data *md)
{
	if (md->message->payload == NULL)
	{
		CTIOT_LOG(LOG_FATAL, "payload is null");
		return;
	}
	char *payload = md->message->payload;
	SetReportPeriodS para = { 0 };
	CtiotMqttDecodeSetReportPeriodPara(payload, &para);
	mqtt_client_s *m_mqtt_client = get_client_handle();
	CtiotSrvCbS *ctiot_callback = m_mqtt_client->downDataCallback;
	if (ctiot_callback != NULL && ctiot_callback->set_report_period_callback != NULL)
	{
		ctiot_callback->set_report_period_callback(&para);
	}
}
CTIOT_RESULT_CODE CtiotMqttSendAirConditionerOnoffRespData(AirConditionerOnoffRespS *para, mqtt_qos_e qos, ctiot_mqtt_msg_s *ptrMsg)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	char *payload = NULL;
	ret = CtiotMqttEncodeAirConditionerOnoffResp(para, &payload);
	if (ret != CTIOT_SUCCESS)
	{
		return ret;
	}
	ret = ctiot_mqtt_send_data("air_conditioner_onoff_resp", qos, payload, ptrMsg);
	CtiotTmodelFree(payload);
	return ret;
}
static void CtiotMqttIntegrateDecodeAirConditionerOnoffCmdCb(MAL_message_data *md)
{
	if (md->message->payload == NULL)
	{
		CTIOT_LOG(LOG_FATAL, "payload is null");
		return;
	}
	char *payload = md->message->payload;
	AirConditionerOnoffCmdS para = { 0 };
	CtiotMqttDecodeAirConditionerOnoffCmdPara(payload, &para);
	mqtt_client_s *m_mqtt_client = get_client_handle();
	CtiotSrvCbS *ctiot_callback = m_mqtt_client->downDataCallback;
	if (ctiot_callback != NULL && ctiot_callback->air_conditioner_onoff_cmd_callback != NULL)
	{
		ctiot_callback->air_conditioner_onoff_cmd_callback(&para);
	}
}
CTIOT_RESULT_CODE CtiotMqttSendIrSensorReportData(IrSensorReportS *para, mqtt_qos_e qos, ctiot_mqtt_msg_s *ptrMsg)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	char *payload = NULL;
	ret = CtiotMqttEncodeIrSensorReport(para, &payload);
	if (ret != CTIOT_SUCCESS)
	{
		return ret;
	}
	ret = ctiot_mqtt_send_data("ir_sensor_report", qos, payload, ptrMsg);
	CtiotTmodelFree(payload);
	return ret;
}
CTIOT_RESULT_CODE CtiotMqttSendInfoReportData(InfoReportS *para, mqtt_qos_e qos, ctiot_mqtt_msg_s *ptrMsg)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	char *payload = NULL;
	ret = CtiotMqttEncodeInfoReport(para, &payload);
	if (ret != CTIOT_SUCCESS)
	{
		return ret;
	}
	ret = ctiot_mqtt_send_data("info_report", qos, payload, ptrMsg);
	CtiotTmodelFree(payload);
	return ret;
}
CTIOT_RESULT_CODE CtiotMqttSendSetAutoControlRespData(SetAutoControlRespS *para, mqtt_qos_e qos, ctiot_mqtt_msg_s *ptrMsg)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	char *payload = NULL;
	ret = CtiotMqttEncodeSetAutoControlResp(para, &payload);
	if (ret != CTIOT_SUCCESS)
	{
		return ret;
	}
	ret = ctiot_mqtt_send_data("set_auto_control_resp", qos, payload, ptrMsg);
	CtiotTmodelFree(payload);
	return ret;
}
static void CtiotMqttIntegrateDecodeSetAutoControlCb(MAL_message_data *md)
{
	if (md->message->payload == NULL)
	{
		CTIOT_LOG(LOG_FATAL, "payload is null");
		return;
	}
	char *payload = md->message->payload;
	SetAutoControlS para = { 0 };
	CtiotMqttDecodeSetAutoControlPara(payload, &para);
	mqtt_client_s *m_mqtt_client = get_client_handle();
	CtiotSrvCbS *ctiot_callback = m_mqtt_client->downDataCallback;
	if (ctiot_callback != NULL && ctiot_callback->set_auto_control_callback != NULL)
	{
		ctiot_callback->set_auto_control_callback(&para);
	}
}
CTIOT_RESULT_CODE CtiotMqttSendSetReportPeriodRespData(SetReportPeriodRespS *para, mqtt_qos_e qos, ctiot_mqtt_msg_s *ptrMsg)
{
	CTIOT_RESULT_CODE ret = CTIOT_SUCCESS;
	char *payload = NULL;
	ret = CtiotMqttEncodeSetReportPeriodResp(para, &payload);
	if (ret != CTIOT_SUCCESS)
	{
		return ret;
	}
	ret = ctiot_mqtt_send_data("set_report_period_resp", qos, payload, ptrMsg);
	CtiotTmodelFree(payload);
	return ret;
}
#endif
#endif
#endif
